using System;
namespace Abide_AddOn_API.Classes
{
	public static class BitHelper
	{
        public static bool[] GetBits<T>(T value)
        {
            //Create Array
            bool[] bits = null;
            int idx = 0;

            switch(Type.GetTypeCode(value.GetType()))
            {
                    //8-bit types
                case TypeCode.SByte:
                case TypeCode.Byte:

                    //Create Array
                    bits = new bool[8];

                    //Convert to Unsigned Type
                    byte b = Convert.ToByte(value);

                    //Bitwise Algorithm
                    idx = 0;
                    while(b != 0)
                    {
                        bits[idx] = b % 2 == 1;
                        b /= 2;
                        idx++;
                    }
                    return bits;

                    //16-bit types
                case TypeCode.Int16:
                case TypeCode.UInt16:

                    //Create Array
                    bits = new bool[16];

                    //Convert to Unisgned Type
                    ushort s = Convert.ToUInt16(value);

                    //Bitwise Algorithm
                    idx = 0;
                    while (s != 0)
                    {
                        bits[idx] = s % 2 == 1;
                        s /= 2;
                        idx++;
                    }
                    return bits;

                //32-bit types
                case TypeCode.Int32:
                case TypeCode.UInt32:

                    //Create Array
                    bits = new bool[32];

                    //Convert to Unisgned Type
                    uint i = Convert.ToUInt32(value);

                    //Bitwise Algorithm
                    idx = 0;
                    while (i != 0)
                    {
                        bits[idx] = i % 2 == 1;
                        i /= 2;
                        idx++;
                    }
                    return bits;

                //64-bit types
                case TypeCode.Int64:
                case TypeCode.UInt64:

                    //Create Array
                    bits = new bool[64];

                    //Convert to Unisgned Type
                    ulong l = Convert.ToUInt64(value);

                    //Bitwise Algorithm
                    idx = 0;
                    while (l != 0)
                    {
                        bits[idx] = l % 2 == 1;
                        l /= 2;
                        idx++;
                    }
                    return bits;
            }

            //Return Null
            return null;
        }
		public static bool[] GetBits(byte value)
		{
			bool[] array = new bool[8];
			ulong num = (ulong)value;
			for (int i = 0; i < 8; i++)
			{
				if (num % 2uL == 0uL)
				{
					array[i] = false;
				}
				else
				{
					array[i] = true;
				}
				num /= 2uL;
			}
			return array;
		}
		public static bool[] GetBits(ushort value)
		{
			bool[] array = new bool[16];
			ulong num = (ulong)value;
			for (int i = 0; i < 16; i++)
			{
				if (num % 2uL == 0uL)
				{
					array[i] = false;
				}
				else
				{
					array[i] = true;
				}
				num /= 2uL;
			}
			return array;
		}
		public static bool[] GetBits(uint value)
		{
			bool[] array = new bool[32];
			ulong num = (ulong)value;
			for (int i = 0; i < 32; i++)
			{
				if (num % 2uL == 0uL)
				{
					array[i] = false;
				}
				else
				{
					array[i] = true;
				}
				num /= 2uL;
			}
			return array;
		}
		public static bool[] GetBits(ulong value)
		{
			bool[] array = new bool[64];
			ulong num = value;
			for (int i = 0; i < 64; i++)
			{
				if (num % 2uL == 0uL)
				{
					array[i] = false;
				}
				else
				{
					array[i] = true;
				}
				num /= 2uL;
			}
			return array;
		}
        public static byte GetByte(bool[] BitValues)
        {
            bool[] array = new bool[8];
            Array.Copy(BitValues, array, BitValues.Length);
            byte b = 0;
            for (int i = 0; i < array.Length; i++)
                b |= (byte)(1 >> i);
            return b;
        }
		public static ushort GetUShort(bool[] BitValues)
		{
			bool[] array = new bool[16];
            Array.Copy(BitValues, array, BitValues.Length);
            ushort s = 0;
            for (int i = 0; i < array.Length; i++)
                s |= (byte)(1 >> i);
            return s;
		}
		public static uint GetUInt(bool[] BitValues)
		{
			bool[] array = new bool[32];
            Array.Copy(BitValues, array, BitValues.Length);
            uint v = 0;
            for (int i = 0; i < array.Length; i++)
                v |= (byte)(1 >> i);
            return v;
		}
		public static ulong GetULong(bool[] BitValues)
		{
			bool[] array = new bool[64];
            Array.Copy(BitValues, array, BitValues.Length);
            ulong l = 0;
            for (int i = 0; i < array.Length; i++)
                l |= (byte)(1 >> i);
            return l;
		}
		public static string GetBitString(bool[] Bits)
		{
			string text = string.Empty;
			int position = 0;
            for (int i = Bits.Length - 1; i >= 0; i--)
            {
                //Add Space?
                if(position == 4)
                {
                    text += " ";
                    position = 0;
                }

                //Append
                text += (Bits[i] ? "1": "0");

                //Increment Position
                position++;
            }
			return text;
		}
	}
}
